<template>
    <div style="width: 1000px; height: 400px;">
        <div id="myChart" style="width: 800px; height: 400px;"></div>
        <div style="margin-top: 20px; display: flex; justify-content: baseline;">
            <div style="margin-left: 150px;"> 
                <a-button v-if="props.isAdmin == true" size="large" @click="handleAddMapTagBTNClick">增加敌人位置</a-button>
                <a-button v-else size="large" @click="handleAddMapTagBTNClick">添加角色位置</a-button>
            </div>
            <div style="margin-left: 50px;">
                <a-button v-if="props.isAdmin == true" size="large" @click="handleRemoveMapTagBTNClick">删除敌人</a-button>
                <a-button v-else size="large" @click="handleRemoveMapTagBTNClick">删除角色</a-button>
            </div>
            <div style="margin-left: 50px;" v-if="props.isAdmin == true" >
                <a-upload
                    action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
                    :headers="headers"
                    @change="handleChange"
                >
                    <a-button size="large">
                        <upload-outlined></upload-outlined>
                        上传地图
                    </a-button>
                </a-upload>
            </div>
        </div>
    </div>
    <a-modal v-bind:open="mapAddTagModelVisible" @ok="handleAddMapTagSave" @cancel="handleAddMapTagCancel">
        <a-form
            :model="addMapTagFormState"
            name="basic"
            :label-col="{ span: 8 }"
            :wrapper-col="{ span: 14 }"
            autocomplete="off"
            @finish="handleAddMapTagSave"
        >
            <a-form-item
                label="角色名"
                name="characterName"
            >
                <a-input v-model:value="addMapTagFormState.characterName" placeholder="角色名"/>
            </a-form-item>
            <a-form-item
                label="x轴坐标"
                name="xPos"
            >
                <a-input v-model:value="addMapTagFormState.xPos" placeholder="角色唯一标识名，不可与其他角色的唯一标识名重复"/>
            </a-form-item>
            <a-form-item
                label="y轴坐标"
                name="yPos"
            >
                <a-input v-model:value="addMapTagFormState.yPos" placeholder="骰娘记录属性"/>
            </a-form-item>
            <a-form-item :wrapper-col="{ span: 14, offset: 10 }">
                <a-button type="primary" html-type="submit">添加</a-button>
            </a-form-item>
        </a-form>
        <template #footer>
        </template>
    </a-modal>
    <a-modal v-bind:open="mapRemoveTagModelVisible" @ok="handleRemoveMapTagSave" @cancel="handleRemoveMapTagCancel">
        <div style="display: flex; justify-content: center;">
            <a-select
                :options="mapRemoveDataAll"
                v-model:value="mapRemoveDataIndex"
            />
        </div>
        <div style="display: flex; justify-content: center; margin-top: 30px">
            <a-button type="primary" @click="handleRemoveMapTagSave">删除</a-button>
        </div>
        <template #footer>
        </template>
    </a-modal>
</template>

<script lang="ts">
export default {
    name: 'RoomMap',
}
</script>

<script setup lang="ts">
import * as echarts from 'echarts';
import { ref, onMounted, reactive } from 'vue';

const props = defineProps(['roomId', 'isAdmin'])

type EChartsOption = echarts.EChartsOption;

var myChart:echarts.ECharts

const symbolSize = 20;
const mapData = [
  {value:[40, -10], name: 'a', type: 'enimy', itemStyle: {color: 'red'}},
  {value:[-30, -5], name: 'b', type: 'player', itemStyle: {color: 'blue'}},
];

let img = new Image();
img.src = 'https://www.boxuegu.com/assets/user/background1.png';

function updatePosition() {
  myChart.setOption({
    graphic: mapData.map(function (item, dataIndex) {
      return {
        position: myChart.convertToPixel('grid', item.value)
      };
    })
  });
}

function showTooltip(dataIndex: number) {
  myChart.dispatchAction({
    type: 'showTip',
    seriesIndex: 0,
    dataIndex: dataIndex
  });
}

function hideTooltip(dataIndex: number) {
  myChart.dispatchAction({
    type: 'hideTip'
  });
}

function onPointDragging(dataIndex: number, pos: number[]) {
  let tmp = myChart.convertFromPixel('grid', pos);
  mapData[dataIndex].value[0] = tmp[0];
  mapData[dataIndex].value[1] = tmp[1];

  // Update data
  myChart.setOption({
    series: [
      {
        data: mapData
      }
    ]
  });
}

onMounted(() => {
    var chartDom = document.getElementById('myChart')!;
    myChart = echarts.init(chartDom);
    var option: EChartsOption = {
        title: {
            text: 'Try Dragging these Points',
            left: 'center'
        },
        tooltip: {
            triggerOn: 'none',
            formatter: function (params: any) {
                return (
                    'X: ' +
                    params.data.value[0].toFixed(2) +
                    '<br>Y: ' +
                    params.data.value[1].toFixed(2)
                );
            }
        },
        grid: {
            top: '8%',
            bottom: '12%'
        },
        xAxis: {
            min: -100,
            max: 100,
            type: 'value',
            axisLine: { onZero: false }
        },
        yAxis: {
            min: -100,
            max: 100,
            type: 'value',
            axisLine: { onZero: false }
        },
        dataZoom: [
            {
                type: 'slider',
                xAxisIndex: 0,
                filterMode: 'none'
            },
            {
                type: 'slider',
                yAxisIndex: 0,
                filterMode: 'none'
            },
            {
                type: 'inside',
                xAxisIndex: 0,
                filterMode: 'none'
            },
            {
                type: 'inside',
                yAxisIndex: 0,
                filterMode: 'none'
            }
        ],
        series: [{
            type: 'scatter',
            symbolSize: symbolSize,
            data: mapData,
            label: {
                show: true,
                position: 'top',
                fontSize: '15px',
                formatter: function (params:any) {
                    return params.name;
                }
            }
        }],
        backgroundColor: {
            image: img,
            repeat: 'no-repeat'
        }
    };
    setTimeout(function () {
        // Add shadow circles (which is not visible) to enable drag.
        myChart.setOption({
            graphic: mapData.map(function (item, dataIndex) {
                return {
                    type: 'circle',
                    position: myChart.convertToPixel('grid', item.value),
                    shape: {
                        cx: 0,
                        cy: 0,
                        r: symbolSize / 2
                    },
                    invisible: true,
                    draggable: true,
                    ondrag: function (dx: number, dy: number) {
                        onPointDragging(dataIndex, [(this as any).x, (this as any).y]);
                    },
                    onmousemove: function () {
                        showTooltip(dataIndex);
                    },
                    onmouseout: function () {
                        hideTooltip(dataIndex);
                    },
                    z: 100
                };
            }),
        });
    }, 0);
    option && myChart.setOption(option);
    window.addEventListener('resize', updatePosition);
    myChart.on('dataZoom', updatePosition);
});

const mapDataChange = () => {
    myChart.setOption({
        series: [
            {
                data: mapData
            }
        ],
        graphic: mapData.map(function (item, dataIndex) {
            return {
                type: 'circle',
                position: myChart.convertToPixel('grid', item.value),
                shape: {
                    cx: 0,
                    cy: 0,
                    r: symbolSize / 2
                },
                invisible: true,
                draggable: true,
                ondrag: function (dx: number, dy: number) {
                    onPointDragging(dataIndex, [(this as any).x, (this as any).y]);
                },
                onmousemove: function () {
                    showTooltip(dataIndex);
                },
                onmouseout: function () {
                    hideTooltip(dataIndex);
                },
                z: 100
            };
        })
    });
}

const mapAddTagModelVisible = ref<boolean>(false)
const addMapTagFormState = reactive({
    characterName: '',
    xPos: 0,
    yPos: 0
})
const handleAddMapTagBTNClick = () => {
    mapAddTagModelVisible.value = true
}
const handleAddMapTagSave = () => {
    mapData.push({
        value:[addMapTagFormState.xPos, addMapTagFormState.yPos], 
        name: addMapTagFormState.characterName, 
        type: 'enimy', 
        itemStyle: {color: 'red'}
    })
    mapDataChange()
    mapAddTagModelVisible.value = false
}
const handleAddMapTagCancel = () => {
    mapAddTagModelVisible.value = false
}

const mapRemoveTagModelVisible = ref<boolean>(false)
const mapRemoveDataAll = ref<any[]>([])
const mapRemoveDataIndex = ref<number>(-1)
const handleRemoveMapTagBTNClick = () => {
    mapRemoveTagModelVisible.value = true
    mapRemoveDataAll.value = []
    mapData.forEach((item, index) => {
        mapRemoveDataAll.value.push({
            label: item.name,
            value: index
        })
    })
}
const handleRemoveMapTagSave = () => {
    mapData.splice(mapRemoveDataIndex.value, 1)
    mapDataChange()
    mapRemoveTagModelVisible.value = false
}
const handleRemoveMapTagCancel = () => {
    mapRemoveTagModelVisible.value = false
}

</script>